﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Globalization;

namespace OEMS
{
    /// <summary>
    /// Deze klasse bevat de code achter de VisualisatieSettingsForm en zorgt dus voor de juiste handelingen van de componenten
    /// </summary>
    /// <author>Mathieu Cruts</author>
    public partial class VisualisatieSettingsForm : Form
    {

        private List <Color> defaultKleurenList = new List<Color> { Color.Blue, Color.Aqua, Color.LightGreen, Color.Yellow, Color.Orange, Color.Crimson };
        private String[] colorNames = System.Enum.GetNames(typeof(KnownColor));



        /// <summary>
        /// Default constructor (die de defaultwaardes instelt)
        /// </summary>
        /// <author>Mathieu Cruts</author>
        public VisualisatieSettingsForm()
        {
            InitializeComponent();

            this.setDefaults();
        }


        /// <summary>
        /// Handelt de "meer kleuren"-button af door een instantie te maken van de ColorPaletteDialogForm
        /// </summary>
        /// <author>Mathieu Cruts</author>
        private void colorDialogButton_Click(object sender, EventArgs e)
        {
            Color color;

            // Haalt de coordinaten op van de geklikte button en opent op basis van deze de colorpicker
            Button button = (Button)sender;
            Point p = new Point(button.Left, button.Top + button.Height);
            p = this.PointToScreen(p);

            ColorPaletteDialogForm clDlg = new ColorPaletteDialogForm(p.X, p.Y);
            clDlg.ShowDialog();

            // Als er op OK gedrukt wordt, worsdt de kleur toegevoegd aan de lijst en wordt deze aangevinkt
            if (clDlg.DialogResult == DialogResult.OK)
            {
                color = clDlg.Color;

                addChosenColor(color.Name);
                this.colorListBox.SetItemChecked((colorListBox.Items.Count - 1), true);
            }

            Invalidate();

            clDlg.Dispose();
        }


        /// <summary>
        /// Handelt de "selecteer alle kleuren"-knop door alle kleuren aan te vinken in de lijst
        /// </summary>
        /// <author>Mathieu Cruts</author>
        private void selectAllColorsButton_Click(object sender, EventArgs e)
        {
            checkOrUncheckAllColors(true);
        }


        /// <summary>
        /// Handelt de checkbox "defaults" af, eerst wordt er nagekeken of deze net is aangezet of uitgezet
        /// </summary>
        /// <author>Mathieu Cruts</author>
        private void defaultSettingsCheckbox_CheckedChanged(object sender, EventArgs e)
        {
            if (this.defaultSettingsCheckbox.Checked == true)
            {
                this.colorListBox.Items.Clear();
                this.setDefaults();
                this.enableOrDisableControls(false);
            }
            else
            {
                this.checkOrUncheckAllColors(false);
                this.enableOrDisableControls(true);
            }
        }


        /// <summary>
        /// Handelt de save-button af, maar zorgt ook eerst voor foutcontrole
        /// </summary>
        /// <author>Mathieu Cruts</author>
        private void saveButton_Click(object sender, EventArgs e)
        {
            Boolean success = addDataToSettings();

            if (success)
            {
                this.Close();
            }
            else
            {
                return;
            }
        }


        /// <summary>
        /// Voegt de gekozen kleur toe aan de lijst
        /// </summary>
        /// <param name="colorName">naam van de kleur om toe te voegen</param>
        /// <author>Mathieu Cruts</author>
        private void addChosenColor(String colorName)
        {
            Boolean distinct = false;

            distinct = checkForDoubles(colorName);

            if (distinct)
            {
                this.colorListBox.Items.Add(colorName.ToString());
                this.colorListBox.SetItemChecked((colorListBox.Items.Count - 1), true);
            }
            else
            {
                MessageBox.Show("U heeft deze kleur (" + colorName + ") reeds geselecteerd, gelieve een andere kleur te kiezen.", "Kleurconflict", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

        }


        /// <summary>
        /// Method die nakijkt of de kleur die de gebruiker wil toevoegen al in de lijst aanwezig is
        /// </summary>
        /// <param name="colorName">naam van de kleur om toe te voegen</param>
        /// <author>Mathieu Cruts</author>
        private Boolean checkForDoubles(String colorName)
        {
            colorName = colorName.ToLower();

            for (int i = 0; i < colorListBox.Items.Count; i++)
            {
                if (colorListBox.Items[i].ToString().ToLower().Equals(colorName))
                {
                    return false;
                }
            }

            return true;
        }


        /// <summary>
        /// Stelt de standaard instellingen in
        /// </summary>
        /// <author>Mathieu Cruts</author>
        private void setDefaults()
        {
            foreach (Color color in defaultKleurenList)
            {
                this.colorListBox.Items.Add(color.Name);
            }

            this.checkOrUncheckAllColors(true);

            this.xAxisTextBox.Text = "0.5";
            this.yAxisTextBox.Text = "0.5";
        }


        /// <summary>
        /// Vinkt alle kleuren in de lijst aan of uit afhankelijk van de booleaanse waarde
        /// </summary>
        /// <param name="check">booleaanse waarde die aangeeft of er aan- of uitgevinkt moet worden</param>
        /// <author>Mathieu Cruts</author>
        private void checkOrUncheckAllColors(Boolean check)
        {
            for (int i = 0; i < colorListBox.Items.Count; i++)
            {
                this.colorListBox.SetItemChecked(i, check);
            }
        }


        /// <summary>
        /// Maakt de tekstboxen van de as-intervallen leeg
        /// </summary>
        /// <author>Mathieu Cruts</author>
        private void clearTextBoxes()
        {
            xAxisTextBox.Text = "";
            yAxisTextBox.Text = "";
        }


        /// <summary>
        /// Maakt alle componenten bruikbaar of net niet bruikbaar afhankelijk van de booleaanse waarde
        /// </summary>
        /// <param name="check">booleaanse waarde die aangeeft of ze bruikbaar of net niet moeten worden</param>
        /// <author>Mathieu Cruts</author>
        private void enableOrDisableControls(Boolean enable)
        {
            if (enable)
            {
                this.colorListBox.Enabled = true;
                this.colorDialogButton.Enabled = true;
                this.selectAllColorsButton.Enabled = true;
                this.emptyAllButton.Enabled = true;
                this.xAxisTextBox.Enabled = true;
                this.yAxisTextBox.Enabled = true;
            }
            else
            {
                this.colorListBox.Enabled = false;
                this.colorDialogButton.Enabled = false;
                this.selectAllColorsButton.Enabled = false;
                this.emptyAllButton.Enabled = false;
                this.xAxisTextBox.Enabled = false;
                this.yAxisTextBox.Enabled = false;
            }
        }


        /// <summary>
        /// Voegt alle data toe aan onze settings
        /// </summary>
        /// <returns>booleaanse waarde of het gelukt is of niet</returns>
        /// <author>Mathieu Cruts</author>
        private Boolean addDataToSettings()
        {

            decimal[] intervalValues = new decimal[2];

            // Kijkt de as-intervaltekstboxen na op fouten
            intervalValues = checkIntervalsForErrors(xAxisTextBox.Text, yAxisTextBox.Text);

            if (intervalValues[0] == -1)
            {
                return false;
            }

            if (colorListBox.CheckedItems.Count < 5)
            {
                MessageBox.Show("Voor een mooie weergave moet u minstens 5 kleuren selecteren.\n\nProbeer opnieuw aub.", "Te weinig kleuren", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }

            else
            {
                Properties.Settings.Default.xAxisInterval = intervalValues[0];
                Properties.Settings.Default.yAxisInterval = intervalValues[1];

                Properties.Settings.Default.GraphColors.Clear();

                for (int i = 0; i < colorListBox.CheckedItems.Count; i++)
                {
                    Properties.Settings.Default.GraphColors.Add(colorListBox.CheckedItems[i].ToString());
                }

                return true;
            }

        }


        /// <summary>
        /// Kijkt de as-intervaltekstboxen na op fouten
        /// </summary>
        /// <param name="text1">tekst uit de x-as tekstbox</param>
        /// <param name="text1">tekst uit de y-as tekstbox</param>
        /// <returns>array met de omgevormde decimale as-intervallen</returns>
        /// <author>Mathieu Cruts</author>
        private decimal[] checkIntervalsForErrors(String text1, String text2)
        {
            decimal[] intervalArray = new decimal[2];

            // Cultuur-onafhankelijk maken + '.' instellen als komma 
            CultureInfo ci = CultureInfo.InvariantCulture.Clone() as CultureInfo;
            ci.NumberFormat.NumberDecimalSeparator = ".";

            text1 = (text1.Contains(',')) ? text1.Replace(',', '.') : text1;
            text2 = (text2.Contains(',')) ? text2.Replace(',', '.') : text2;

            try
            {
               intervalArray[0] = Decimal.Parse(text1, ci);
               intervalArray[1] = Decimal.Parse(text2, ci);
            }

            catch (FormatException)
            {
                MessageBox.Show("U gaf geen geldige waarde in voor de as-intervallen.\n\nProbeer opnieuw aub.", "As-interval fout", MessageBoxButtons.OK, MessageBoxIcon.Error);
                intervalArray[0] = -1;
                intervalArray[1] = -1;
                return intervalArray;
            }

            foreach (double d in intervalArray)
            {
                if (d == 0)
                {
                    MessageBox.Show("Een interval van 0 is niet mogelijk.\n\nProbeer opnieuw aub.", "As-interval fout", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    intervalArray[0] = -1;
                    intervalArray[1] = -1;
                    return intervalArray;

                }
                else if (d < 0.05)
                {
                    MessageBox.Show("Een interval kleiner dan 0.05 is niet aan te raden.\n\nProbeer opnieuw aub.", "As-interval fout", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    intervalArray[0] = -1;
                    intervalArray[1] = -1;
                    return intervalArray;
                }
            }

            return intervalArray;
        }


        /// <summary>
        /// Maakt alle waardes op de form leeg (kleurenlijst + asintervaltekstboxen)
        /// </summary>
        /// <author>Mathieu Cruts</author>
        private void emptyAllButton_Click(object sender, EventArgs e)
        {
            colorListBox.Items.Clear();
            clearTextBoxes();
        }

    }
}
